using System;
using CommonDomain.Persistence;

namespace Sponsorship.Domain.Memberships
{
    /// <summary>
    /// Handles domain commands dealing with <see cref="Membership"/> instances.
    /// </summary>
    public class MembershipCommandHandler :
        ICommandHandler<EnterMembership>,
        ICommandHandler<ChangeMembership>,
        ICommandHandler<DeleteMembership>
    {
        private readonly IRepository _repository;

        public MembershipCommandHandler (IRepository repository)
        {
            _repository = repository;
        }

        public void Handle (EnterMembership command)
        {
            var membership = new Membership (command.MembershipId, command.MembershipTypeId, command.PersonId, command.SponsorId, command.Amount, command.StartDate, command.EndDate, command.Period, command.Comment);
            SaveMembership (membership);
        }

        public void Handle (ChangeMembership command)
        {
            Membership membership = LoadMembership (command.SponsorId, command.Version);

            //execute domain logic and get back a new aggregate
            membership.Delete();

            //save new raised events of aggregate into eventstore
            SaveMembership (membership);
        }

        public void Handle (DeleteMembership command)
        {
            Membership membership = LoadMembership(command.MembershipId, command.Version);

            //execute domain logic and get back a new aggregate
            membership.Delete();

            //save new raised events of aggregate into eventstore
            SaveMembership(membership);
        }

        private Membership LoadMembership (Guid guid)
        {
            return _repository.GetById<Membership> (guid);
        }

        private Membership LoadMembership (Guid guid, int version)
        {
            return _repository.GetById<Membership> (guid, version);
        }

        private void SaveMembership (Membership membership)
        {
            _repository.Save (membership, Guid.NewGuid()); // Every commit has a new ID
        }
    }
}